package com.demo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * 消息设定过期时间
 *
 * 给消息设定一个过期时间，超过这个时间消息没有被取走的消息就会被删除
 * 我们可以从两个层面来给消息设定过期时间：
 *      1、队列层面: 在队列层面设定消息的过期时间，并不是队列的过期时间，意思是这个队列中的消息全部使用同一个过期时间。
 *      2、消息本身：给具体的某个消息设定过期时间
 * 如果两个层面都做了设置，那么哪个时间短，哪个生效。
 */
@Configuration
@Slf4j
public class RabbitConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void initRabbitTemplate(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        //消息发送到交换机 成功|失败 都会调用这个方法
        log.info("confirm() 回调函数打印 CorrelationData：{}", correlationData);
        log.info("confirm() 回调函数打印 ack：{}", ack);
        log.info("confirm() 回调函数打印 cause：{}", cause);
    }

    @Override
    public void returnedMessage(ReturnedMessage returned) {
        //发送到队列失败时才会调用这个方法
        log.info("returnedMessage() 回调函数 消息主体：{}", new String(returned.getMessage().getBody()));
        log.info("returnedMessage() 回调函数 应答码：{}", returned.getReplyCode());
        log.info("returnedMessage() 回调函数 描述：{}", returned.getReplyText());
        log.info("returnedMessage() 回调函数 消息使用的交换器 exchange：{}", returned.getExchange());
        log.info("returnedMessage() 回调函数 消息使用的路由键 routingKey：{}", returned.getRoutingKey());
    }
}
